﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media.Animation;

namespace AgLux
{
    /// <summary>
    /// Represents a component that displays animated graphics.
    /// </summary>

    public class Animation : Component
    {
        private Canvas _animationArea;
        private Storyboard _animation;
        private MouseEventHandler _pressHandler;
        private bool _isAutostarting;

        /// <summary>
        /// Initializes a new instance of the Animation class.
        /// </summary>

        /// <param name="source">
        /// The XAML source.
        /// </param>

        /// <param name="caption">
        /// The animation caption.
        /// </param>

        /// <param name="autostarting">
        /// Whether the animation is autostarting.
        /// </param>

        public Animation(string source, string caption, bool autostarting)
            : base()
        {
            _animationArea = (Canvas)_resource.FindName("animationArea");
            _animation = null;
            _pressHandler = new MouseEventHandler(BePressed);
            _isAutostarting = autostarting;

            _caption.Text = caption;

            Downloader downloader = new Downloader();
            downloader.Completed += new EventHandler(Load);
            downloader.Open("GET", new Uri(source, UriKind.Relative));
            downloader.Send();
        }

        /// <summary>
        /// Prepare to display the component.
        /// </summary>

        /// <param name="width">
        /// The width of the canvas on which the component will be displayed.
        /// </param>

        public override void Prepare(double width)
        {
            Width = _screen.Width = width;
            if (_animationArea.Width < width)
            {
                _screen.Width = _animationArea.Width;
            }

            if (_animationArea.Width > 0 && _animationArea.Height > 0)
            {
                _screen.Height = _animationArea.Height;
                SetCaption(_screen.Width);
                Height = _screen.Height + _caption.Height + 5;
                _caption.SetValue(Canvas.TopProperty, Height - _caption.Height);
            }
        }

        /// <summary>
        /// Ends the activity of the component.
        /// </summary>

        public override void End()
        {
            base.End();
            if (_animation != null)
            {
                _animation.Stop();
                if (!_isAutostarting)
                {
                    _screen.MouseLeftButtonDown += _pressHandler;
                }
            }
        }

        /// <summary>
        /// Occurs when the downloading is completed.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected void Load(object sender, EventArgs args)
        {
            Downloader downloader = (Downloader)sender;
            _animationArea = (Canvas)XamlReader.Load(downloader.ResponseText);
            _screen.Children.Add(_animationArea);

            for (int i = 0; i < _animationArea.Resources.Count && _animation == null; i++)
            {
                if (_animationArea.Resources[i].GetType() == new Storyboard().GetType())
                {
                    _animation = (Storyboard)_animationArea.Resources[i];
                }
            }

            if (_animation != null && !_isAutostarting)
            {
                _screen.MouseLeftButtonDown += _pressHandler;
                _animation.Completed += new EventHandler(MakePressable);
            }
        }

        /// <summary>
        /// Occurs when it is time to start the activity of the component.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected override void Start(object sender, EventArgs args)
        {
            base.Start(sender, args);
            if (_animation != null && _isAutostarting)
            {
                _animation.Begin();
            }
        }

        /// <summary>
        /// Occurs when the component is pressed.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The MouseEventArgs that contains the event data.
        /// </param>

        protected void BePressed(object sender, MouseEventArgs args)
        {
            _screen.MouseLeftButtonDown -= _pressHandler;
            _animation.Begin();
        }

        /// <summary>
        /// Occurs when the animation is completed.
        /// </summary>

        /// <param name="sender">
        /// The object that raised the event.
        /// </param>

        /// <param name="args">
        /// The EventArgs that contains the event data.
        /// </param>

        protected void MakePressable(object sender, EventArgs args)
        {
            _screen.MouseLeftButtonDown += _pressHandler;
        }
    }
}
